Bug 143330, support update counter spec.
authorSoeren Sandmann <sandmann@daimi.au.dk>
Sun, 11 Jul 2004 13:26:57 +0000 (13:26 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Sun, 11 Jul 2004 13:26:57 +0000 (13:26 +0000)
Sun Jul 11 15:24:03 2004  Soeren Sandmann  <sandmann@daimi.au.dk>

Bug 143330, support update counter spec.

* configure.in: Add check for the Sync extension

* gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
gdk_window_configure_finished()

* gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
* gtk/gtkwindow.c (gtk_window_realize): Automatically enable
synchronized configures.

* gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
and pending counter values.

* gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
* gdk/x11/gdkwindow-x11.c
(gdk_window_enable_synchronized_configure): New function.
* gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
Delete update counter.
* gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
_NET_WM_SYNC_REQUEST when Sync is available

* gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
_NET_WM_SYNC_REQUEST messages
* gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
value for use by gdk_window_configure_finished() when receiving
ConfigureNotifies.

* gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
* gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
extension is available
* gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
_NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.

* gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
stubs for enable_synchronized_configure() and configure_finished()

14 files changed:
ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
configure.in
gdk/gdkwindow.h
gdk/linux-fb/gdkwindow-fb.c
gdk/win32/gdkwindow-win32.c
gdk/x11/gdkdisplay-x11.c
gdk/x11/gdkdisplay-x11.h
gdk/x11/gdkevents-x11.c
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkwindow-x11.h
gtk/gtkwindow.c

index 5002b46a4e9fbff937c72a58020219625d81ae11..19d419d7ca9af1f22f586c875ee450339bf48b5b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+Sun Jul 11 15:24:03 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 143330, support update counter spec.
+       
+       * configure.in: Add check for the Sync extension
+
+       * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+       gdk_window_configure_finished()
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+       * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+       synchronized configures.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+       and pending counter values. 
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+       * gdk/x11/gdkwindow-x11.c
+       (gdk_window_enable_synchronized_configure): New function.
+       * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+       Delete update counter.
+       * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+       _NET_WM_SYNC_REQUEST when Sync is available
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+       _NET_WM_SYNC_REQUEST messages
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+       value for use by gdk_window_configure_finished() when receiving
+       ConfigureNotifies.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+       extension is available
+       * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+       _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+       * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+       stubs for enable_synchronized_configure() and configure_finished()
+
 Sat Jul 10 23:35:13 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkentry.c (paste_received): Make middle-button pasting
index 5002b46a4e9fbff937c72a58020219625d81ae11..19d419d7ca9af1f22f586c875ee450339bf48b5b 100644 (file)
@@ -1,3 +1,42 @@
+Sun Jul 11 15:24:03 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 143330, support update counter spec.
+       
+       * configure.in: Add check for the Sync extension
+
+       * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+       gdk_window_configure_finished()
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+       * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+       synchronized configures.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+       and pending counter values. 
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+       * gdk/x11/gdkwindow-x11.c
+       (gdk_window_enable_synchronized_configure): New function.
+       * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+       Delete update counter.
+       * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+       _NET_WM_SYNC_REQUEST when Sync is available
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+       _NET_WM_SYNC_REQUEST messages
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+       value for use by gdk_window_configure_finished() when receiving
+       ConfigureNotifies.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+       extension is available
+       * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+       _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+       * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+       stubs for enable_synchronized_configure() and configure_finished()
+
 Sat Jul 10 23:35:13 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkentry.c (paste_received): Make middle-button pasting
index 5002b46a4e9fbff937c72a58020219625d81ae11..19d419d7ca9af1f22f586c875ee450339bf48b5b 100644 (file)
@@ -1,3 +1,42 @@
+Sun Jul 11 15:24:03 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 143330, support update counter spec.
+       
+       * configure.in: Add check for the Sync extension
+
+       * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+       gdk_window_configure_finished()
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+       * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+       synchronized configures.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+       and pending counter values. 
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+       * gdk/x11/gdkwindow-x11.c
+       (gdk_window_enable_synchronized_configure): New function.
+       * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+       Delete update counter.
+       * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+       _NET_WM_SYNC_REQUEST when Sync is available
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+       _NET_WM_SYNC_REQUEST messages
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+       value for use by gdk_window_configure_finished() when receiving
+       ConfigureNotifies.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+       extension is available
+       * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+       _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+       * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+       stubs for enable_synchronized_configure() and configure_finished()
+
 Sat Jul 10 23:35:13 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkentry.c (paste_received): Make middle-button pasting
index 5002b46a4e9fbff937c72a58020219625d81ae11..19d419d7ca9af1f22f586c875ee450339bf48b5b 100644 (file)
@@ -1,3 +1,42 @@
+Sun Jul 11 15:24:03 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       Bug 143330, support update counter spec.
+       
+       * configure.in: Add check for the Sync extension
+
+       * gdk/gdkwindow.h: gdk_window_enable_synchronized_configure() and
+       gdk_window_configure_finished()
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Call gdk_window_finish_configure().
+       * gtk/gtkwindow.c (gtk_window_realize): Automatically enable
+       synchronized configures.
+
+       * gdk/x11/gdkwindow-x11.h (struct _GdkToplevelX11): Store current
+       and pending counter values. 
+
+       * gdk/x11/gdkwindow-x11.c (gdk_window_configure_finished): New function.
+       * gdk/x11/gdkwindow-x11.c
+       (gdk_window_enable_synchronized_configure): New function.
+       * gdk/x11/gdkwindow-x11.c (gdk_toplevel_x11_free_contents):
+       Delete update counter.
+       * gdk/x11/gdkwindow-x11.c (set_wm_protocols): Advertise
+       _NET_WM_SYNC_REQUEST when Sync is available
+
+       * gdk/x11/gdkevents-x11.c (gdk_wm_protocols_filter): Handle
+       _NET_WM_SYNC_REQUEST messages
+       * gdk/x11/gdkevents-x11.c (gdk_event_translate): Save counter
+       value for use by gdk_window_configure_finished() when receiving
+       ConfigureNotifies.
+
+       * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add use_sync flag
+       * gdk/x11/gdkdisplay-x11.c (gdk_display_open): Check if the XSync
+       extension is available
+       * gdk/x11/gdkdisplay-x11.c: Add _NET_WM_SYNC_REQUEST and
+       _NET_WM_SYNC_REQUEST_COUNTER to list of supported atoms.
+
+       * gdk/linux-fb/gdkwindow-fb.c, gdk/win32/gdkwindow-win32.c: Add
+       stubs for enable_synchronized_configure() and configure_finished()
+
 Sat Jul 10 23:35:13 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtkentry.c (paste_received): Make middle-button pasting
index 6e7d1ef561f40126638b97f60586e9f29a7f9936..c011f343a251a06a6d012e5d42f543a9ee80a53b 100644 (file)
@@ -1208,6 +1208,12 @@ if test "x$gdktarget" = "xx11"; then
     GDK_EXTRA_LIBS="`$PKG_CONFIG --libs xcursor` $GDK_EXTRA_LIBS"
   fi
 
+  # X SYNC check
+  AC_CHECK_LIB(Xext, XSyncQueryExtension,
+               [GTK_ADD_LIB(x_extra_libs,Xext)
+               AC_DEFINE([HAVE_XSYNC], [], [Have SYNC extension])],
+               ,$x_libs_for_checks)
+
   # Checks for XFixes extension
   
   have_xfixes=false
index 83ce70391adc5c701e0c35abf0235cde066815f5..ce44309dc0e473284b5b0dd23eb1e9d6ba366a48 100644 (file)
@@ -564,6 +564,9 @@ void gdk_window_get_internal_paint_info (GdkWindow    *window,
                                         gint         *x_offset,
                                         gint         *y_offset);
 
+void gdk_window_enable_synchronized_configure (GdkWindow *window);
+void gdk_window_configure_finished            (GdkWindow *window);
+
 #ifndef GDK_MULTIHEAD_SAFE
 GdkPointerHooks *gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks);   
 #endif /* GDK_MULTIHEAD_SAFE */
index 6f746df491fb8b821b475026d7ab2ccaf742d9da..8a24025bc17287f89cc104ae9b064caa333d1131 100644 (file)
@@ -2359,3 +2359,13 @@ gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
 
   return (GdkWindow*) (anid);
 }
+
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+}
+
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
+}
index cd585b1aec848005c612d63e4255658cc16b09cb..87942b29154e9db0ffe8868f45f8d030890bab51 100644 (file)
@@ -3227,3 +3227,13 @@ gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
 
   return gdk_window_lookup (anid);
 }
+
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+}
+
+void
+gdk_window_configure_finished (GdkWindow *window);
+{
+}
index ed25df60f79c584e689e62d132f3d94113abfd26..705dccacc845bc4fdb12276c187cc8d25e917bb5 100644 (file)
@@ -83,6 +83,8 @@ static const char *const precache_atoms[] = {
   "_NET_WM_STATE_MAXIMIZED_VERT",
   "_NET_WM_STATE_MAXIMIZED_HORZ",
   "_NET_WM_STATE_FULLSCREEN",
+  "_NET_WM_SYNC_REQUEST",
+  "_NET_WM_SYNC_REQUEST_COUNTER",
   "_NET_WM_WINDOW_TYPE",
   "_NET_WM_WINDOW_TYPE_NORMAL",
   "_NET_WM_USER_TIME",
@@ -280,6 +282,20 @@ gdk_display_open (const gchar *display_name)
   }
 #endif
 
+  display_x11->use_sync = FALSE;
+#ifdef HAVE_XSYNC
+  {
+    int major, minor;
+    int error_base, event_base;
+    
+    if (XSyncQueryExtension (display_x11->xdisplay,
+                            &event_base, &error_base) &&
+        XSyncInitialize (display_x11->xdisplay,
+                         &major, &minor))
+      display_x11->use_sync = TRUE;
+  }
+#endif
+  
   _gdk_windowing_image_init (display);
   _gdk_events_init (display);
   _gdk_input_init (display);
index 3ce7d941aa5ca3f64327399e99148151218f7f47..a523da94091af3405e5d46b35ac9be487a444977 100644 (file)
@@ -147,6 +147,7 @@ struct _GdkDisplayX11
   guint base_dnd_atoms_precached : 1;
   guint xdnd_atoms_precached : 1;
   guint motif_atoms_precached : 1;
+  guint use_sync : 1;
 };
 
 struct _GdkDisplayX11Class
index b4a0ba202a311a65ed48e01bc9bfff7a03a84cb6..825128713b58e92a8d9e93e20579d7886f99e80f 100644 (file)
 #include <X11/XKBlib.h>
 #endif
 
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
 #ifdef HAVE_XFIXES
 #include <X11/extensions/Xfixes.h>
 #endif
@@ -215,11 +219,10 @@ _gdk_events_init (GdkDisplay *display)
 
   display_sources = g_list_prepend (display_sources,display_source);
 
-  gdk_display_add_client_message_filter (
-       display,
-       gdk_atom_intern ("WM_PROTOCOLS", FALSE), 
-       gdk_wm_protocols_filter,   
-       NULL);
+  gdk_display_add_client_message_filter (display,
+                                        gdk_atom_intern ("WM_PROTOCOLS", FALSE), 
+                                        gdk_wm_protocols_filter,   
+                                        NULL);
 }
 
 
@@ -1723,8 +1726,16 @@ gdk_event_translate (GdkDisplay *display,
          !GDK_WINDOW_DESTROYED (window) &&
          (window_private->extension_events != 0))
        _gdk_input_configure_event (&xevent->xconfigure, window);
+      
+#ifdef HAVE_XSYNC
+      if (toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
+       {
+         toplevel->current_counter_value = toplevel->pending_counter_value;
+         XSyncIntToValue (&toplevel->pending_counter_value, 0);
+       }
+#endif
 
-      if (!window ||
+    if (!window ||
          xevent->xconfigure.event != xevent->xconfigure.window ||
           GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD ||
           GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT)
@@ -2022,8 +2033,9 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
   XEvent *xevent = (XEvent *)xev;
   GdkWindow *win = event->any.window;
   GdkDisplay *display = GDK_WINDOW_DISPLAY (win);
+  Atom atom = (Atom)xevent->xclient.data.l[0];
 
-  if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
+  if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW"))
     {
   /* The delete window request specifies a window
    *  to delete. We don't actually destroy the
@@ -2041,7 +2053,7 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
 
       return GDK_FILTER_TRANSLATE;
     }
-  else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
+  else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS"))
     {
       GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
       GdkWindowObject *private = (GdkWindowObject *)win;
@@ -2056,7 +2068,7 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
 
       return GDK_FILTER_REMOVE;
     }
-  else if ((Atom) xevent->xclient.data.l[0] == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
+  else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING") &&
           !_gdk_x11_display_is_root_window (display,
                                             xevent->xclient.window))
     {
@@ -2070,7 +2082,21 @@ gdk_wm_protocols_filter (GdkXEvent *xev,
 
       return GDK_FILTER_REMOVE;
     }
-
+  else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST") &&
+          GDK_DISPLAY_X11 (display)->use_sync)
+    {
+      GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (event->any.window);
+      if (toplevel)
+       {
+#ifdef HAVE_XSYNC
+         XSyncIntsToValue (&toplevel->pending_counter_value, 
+                           xevent->xclient.data.l[2], 
+                           xevent->xclient.data.l[3]);
+#endif
+       }
+      return GDK_FILTER_REMOVE;
+    }
+  
   return GDK_FILTER_CONTINUE;
 }
 
index d25c0980fbcc82b8b15cdb640bb163a9269e2b8f..9b749909ac884ada9ba32af58f3b34b05ddf32b3 100644 (file)
@@ -470,13 +470,19 @@ static void
 set_wm_protocols (GdkWindow *window)
 {
   GdkDisplay *display = gdk_drawable_get_display (window);
-  Atom protocols[3];
+  Atom protocols[4];
+  int n = 0;
   
-  protocols[0] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
-  protocols[1] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
-  protocols[2] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
+  protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
+  protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
+  protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
 
-  XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, 3);
+#ifdef HAVE_XSYNC
+  if (GDK_DISPLAY_X11 (display)->use_sync)
+    protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
+#endif
+  
+  XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
 }
 
 static const gchar *
@@ -525,7 +531,8 @@ create_focus_window (Display *xdisplay,
 }
 
 static void
-setup_toplevel_window (GdkWindow *window, GdkWindow *parent)
+setup_toplevel_window (GdkWindow *window, 
+                      GdkWindow *parent)
 {
   GdkWindowObject *obj = (GdkWindowObject *)window;
   GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
@@ -1020,7 +1027,8 @@ gdk_window_lookup (GdkNativeWindow anid)
 }
 
 static void
-gdk_toplevel_x11_free_contents (GdkToplevelX11 *toplevel)
+gdk_toplevel_x11_free_contents (GdkDisplay *display,
+                               GdkToplevelX11 *toplevel)
 {
   if (toplevel->icon_window)
     {
@@ -1042,6 +1050,17 @@ gdk_toplevel_x11_free_contents (GdkToplevelX11 *toplevel)
       g_object_unref (toplevel->group_leader);
       toplevel->group_leader = NULL;
     }
+  if (toplevel->update_counter != None)
+    {
+#ifdef HAVE_XSYNC
+      XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display), 
+                          toplevel->update_counter);
+      toplevel->update_counter = None;
+
+      XSyncIntToValue (&toplevel->current_counter_value, 0);
+      XSyncIntToValue (&toplevel->pending_counter_value, 0);
+#endif
+    }
 }
 
 void
@@ -1062,7 +1081,7 @@ _gdk_windowing_window_destroy (GdkWindow *window,
 
   toplevel = _gdk_x11_window_get_toplevel (window);
   if (toplevel)
-    gdk_toplevel_x11_free_contents (toplevel);
+    gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
 
   draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
     
@@ -1825,7 +1844,8 @@ gdk_window_reparent (GdkWindow *window,
                  _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
                }
                
-             gdk_toplevel_x11_free_contents (impl->toplevel);
+             gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), 
+                                             impl->toplevel);
              g_free (impl->toplevel);
              impl->toplevel = NULL;
            }
@@ -5608,3 +5628,100 @@ gdk_window_begin_move_drag (GdkWindow *window,
   else
     emulate_move_drag (window, button, root_x, root_y, timestamp);
 }
+
+/**
+ * gdk_window_enable_synchronized_configure:
+ * @window: a toplevel #GdkWindow
+ * 
+ * Indicates that the application will cooperate with the window
+ * system in synchronizing the window repaint with the window
+ * manager during resizing operations. After an application calls
+ * this function, it must call gdk_window_configure_finished() every
+ * time it has finished all processing associated with a set of
+ * Configure events. Toplevel GTK+ windows automatically use this
+ * protocol.
+ * 
+ * On X, calling this function makes @window participate in the
+ * _NET_WM_SYNC_REQUEST window manager protocol.
+ * 
+ * Since: 2.6
+ **/
+void
+gdk_window_enable_synchronized_configure (GdkWindow *window)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+#ifdef HAVE_XSYNC
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+      GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+      GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+
+      if (toplevel && toplevel->update_counter == None &&
+         GDK_DISPLAY_X11 (display)->use_sync)
+       {
+         Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+         XSyncValue value;
+         Atom atom;
+         
+         if (toplevel->update_counter != None)
+           return;
+         
+         XSyncIntToValue (&value, 0);
+         
+         toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
+         
+         atom = gdk_x11_get_xatom_by_name_for_display (display,
+                                                       "_NET_WM_SYNC_REQUEST_COUNTER");
+         
+         XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
+                          atom, XA_CARDINAL,
+                          32, PropModeReplace,
+                          (guchar *)&toplevel->update_counter, 1);
+         
+         XSyncIntToValue (&toplevel->current_counter_value, 0);
+       }
+    }
+#endif /* HAVE_XSYNC */
+}
+
+/**
+ * gdk_window_configure_finished:
+ * @window: a toplevel #GdkWindow
+ * 
+ * Signal to the window system that the application has finished
+ * handling Configure events it has received. Window Managers can
+ * use this to better synchronize the frame repaint with the
+ * application. GTK+ applications will automatically call this
+ * function when appropriate.
+ *
+ * This function can only be called if gdk_window_use_configure()
+ * was called previously.
+ *
+ * Since: 2.6
+ **/
+void
+gdk_window_configure_finished (GdkWindow *window)
+{
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_XSYNC
+  if (!GDK_WINDOW_DESTROYED (window))
+    {
+      GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+      GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
+
+      g_return_if_fail (toplevel->update_counter != None);
+      
+      if (toplevel && GDK_DISPLAY_X11 (display)->use_sync &&
+         !XSyncValueIsZero (toplevel->current_counter_value))
+       {
+         XSyncSetCounter (GDK_WINDOW_XDISPLAY (window), 
+                          toplevel->update_counter,
+                          toplevel->current_counter_value);
+         
+         XSyncIntToValue (&toplevel->current_counter_value, 0);
+       }
+    }
+#endif
+}
index e2f160bd73aa20b31a1496375b887465d93e11be..d40110f44c218599902e6a26a233d9de1a63d14f 100644 (file)
 
 #include <gdk/x11/gdkdrawable-x11.h>
 
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
 G_BEGIN_DECLS
 
 typedef struct _GdkToplevelX11 GdkToplevelX11;
@@ -120,13 +124,23 @@ struct _GdkToplevelX11
    * that might not even be part of this app
    */
   Window focus_window;
+#ifdef HAVE_XSYNC
+  XID update_counter;
+  XSyncValue pending_counter_value; /* latest _NET_WM_SYNC_REQUEST value received */
+  XSyncValue current_counter_value; /* Latest _NET_WM_SYNC_REQUEST value received
+                                    * where we have also seen the corresponding
+                                    * ConfigureNotify
+                                    */
+#endif
 };
 
 GType gdk_window_impl_x11_get_type (void);
 
-GdkToplevelX11 *_gdk_x11_window_get_toplevel  (GdkWindow *window);
 void             gdk_x11_window_set_user_time (GdkWindow *window,
                                                guint32    timestamp);
+
+GdkToplevelX11 *_gdk_x11_window_get_toplevel  (GdkWindow *window);
 void           _gdk_x11_window_tmp_unset_bg  (GdkWindow *window,
                                               gboolean   recurse);
 void            _gdk_x11_window_tmp_reset_bg  (GdkWindow *window,
index 45d7143cba9a5c405ef4d9a6d44456c90a8eaff3..9ffe43b7e61943dcfdaac75c809b0ca11a4be07b 100644 (file)
@@ -3965,6 +3965,8 @@ gtk_window_realize (GtkWidget *widget)
   attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
   
   widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
+
+  gdk_window_enable_synchronized_configure (widget->window);
     
   gdk_window_set_user_data (widget->window, window);
       
@@ -4201,7 +4203,10 @@ gtk_window_configure_event (GtkWidget         *widget,
   if (!expected_reply &&
       (widget->allocation.width == event->width &&
        widget->allocation.height == event->height))
-    return TRUE;
+    {
+      gdk_window_configure_finished (widget->window);
+      return TRUE;
+    }
 
   /*
    * If we do need to resize, we do that by:
@@ -5296,6 +5301,10 @@ gtk_window_move_resize (GtkWindow *window)
       allocation = widget->allocation;
       gtk_widget_size_allocate (widget, &allocation);
 
+      gdk_window_process_all_updates ();
+      
+      gdk_window_configure_finished (widget->window);
+
       /* If the configure request changed, it means that
        * we either:
        *   1) coincidentally changed hints or widget properties